package com.sgb.kjwl.view.widget.transport;

import android.Manifest;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.AoiItem;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.apeng.permissions.EsayPermissions;
import com.apeng.permissions.OnPermission;
import com.bigkoo.pickerview.view.OptionsPickerView;
import com.sgb.kjwl.R;
import com.sgb.kjwl.databinding.DialogSelectAddressBinding;
import com.sgb.kjwl.utils.NumberUtil;
import com.sgb.kjwl.utils.PickerHelper;
import com.sgb.kjwl.view.constant.RequestCode;
import com.sgb.kjwl.view.constant.RouterKey;
import com.sgb.kjwl.view.ui.adapter.transport.AMapAddressAdapter;
import com.sgb.link.entity.AMapAddressEntity;
import com.sgb.link.utils.AddressHelper;
import com.sgb.link.utils.LocationUtil;
import com.swgk.core.dialog.RoundDialog;
import com.swgk.core.util.ClickUtils;
import com.swgk.core.util.MToast;
import com.swgk.core.view.areapopup.AddressEntity;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Completable;
import io.reactivex.CompletableObserver;
import io.reactivex.disposables.Disposable;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * 公共地图地址选择
 */
public class AMapDialog extends AppCompatActivity implements View.OnClickListener,
        AMap.OnMyLocationChangeListener, AMap.OnMapClickListener,
        PoiSearch.OnPoiSearchListener, TextView.OnEditorActionListener {
    //地图搜索Poi类型
    private final String POI_TYPE = "汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|" +
            "体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|" +
            "金融保险服务|公司企业|道路附属设施|公共设施";
    private Context context;
    //dataBinding
    private DialogSelectAddressBinding binding;
    //地图控制器
    private AMap aMap;
    //搜索返回的地址数目
    private final int limit = 15;
    //搜索扩展字段 base表示只返回基础数据，all表示所有数据 ，默认 base
    private final String extensions = "all";
    //地图缩放级别
    private final int zoomLevel = 17;
    //是否是地图点击
    private boolean mIsMapClick;
    //地址列表
    private List<AMapAddressEntity> mList;
    private AMapAddressAdapter mAdapter;
    //省市区选择器
    private OptionsPickerView<AddressEntity> mPicker;
    //当前选中城市
    public String mCurCity;
    //当前选中的位置信息
    private AMapAddressEntity selectEntity;
    //地图找车增加字段：0——表示起点地址    1——表示终点地址
    private int type = -1;
    //是否定位完成
    private boolean mIsInitializedLatLng;
    //当前定位位置信息
    private LatLng latLngLocation;

    /**
     * 正常选择
     */
    public static void launch(Activity activity) {
        launch(activity, "", "", 0, 0);
    }

    /**
     * 定位搜索
     */
    public static void launch(Activity activity, double latitude, double longitude) {
        launch(activity, "", "", latitude, longitude);
    }

    /**
     * 地区搜索
     */
    public static void launch(Activity activity, String keyword, String city) {
        launch(activity, keyword, city, 0, 0);
    }

    public static void launch(Activity activity, String keyword, String city, double latitude, double longitude) {
        if (!ClickUtils.isDoubleClick()) {
            realLaunch(activity, -1, keyword, city, latitude, longitude);
        }
    }

    public static void launch(Activity activity, int type, String keyword) {
        if (!ClickUtils.isDoubleClick()) {
            realLaunch(activity, type, keyword, "", 0, 0);
        }
    }

    private static void realLaunch(Activity activity, int type, String keyword, String city, double latitude, double longitude) {
        EsayPermissions.with(activity)
                .permission(Manifest.permission.ACCESS_FINE_LOCATION)
                .request(new OnPermission() {
                    @Override
                    public void hasPermission(List<String> granted, boolean isAll) {
                        Intent intent = new Intent(activity, AMapDialog.class);
                        Bundle bundle = new Bundle();
                        bundle.putString("keyword", keyword);
                        bundle.putString("city", city);
                        bundle.putDouble("latitude", latitude);
                        bundle.putDouble("longitude", longitude);
                        bundle.putInt("type", type);
                        intent.putExtras(bundle);
                        activity.startActivityForResult(intent, RequestCode.CODE_MAP);
                        activity.overridePendingTransition(R.anim.dialog_enter_anim, R.anim.dialog_exit_anim);
                    }

                    @Override
                    public void noPermission(List<String> denied, boolean quick) {
                        showDialog();
                    }

                    //定位dialog
                    private void showDialog() {
                        new RoundDialog.Builder(activity)
                                .title("定位授权")
                                .content("为更好地使用经营帮，请至手机设置界面授权获取地理位置的权限")
                                .confirm("去授权")
                                .cancelable(false)
                                .confirmCallback(v -> {
                                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
                                    intent.setData(uri);
                                    activity.startActivity(intent);
                                }).show();
                    }
                });
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
        init(savedInstanceState);
    }

    /**
     * 初始化操作
     */
    private void init(Bundle savedInstanceState) {
        binding = DataBindingUtil.setContentView(this, R.layout.dialog_select_address);
        binding.setLifecycleOwner(this);
        //
        initMap(savedInstanceState);
        initRecycler();
        initEvent();
        //获取省市区数据
        getAddress();
    }

    /**
     * 初始化地图
     */
    private void initMap(Bundle savedInstanceState) {
        binding.searchMapView.onCreate(savedInstanceState);
        //获取地图控制类
        aMap = binding.searchMapView.getMap();
        //设置缩放级别
        aMap.moveCamera(CameraUpdateFactory.zoomTo(zoomLevel));
        //显示定位蓝点
        aMap.getUiSettings().setMyLocationButtonEnabled(true);
        //启动显示定位蓝点，false表示隐藏定位蓝点并不进行定位，默认是false。
        aMap.setMyLocationEnabled(true);
        //初始化定位蓝点样式类
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        //定位一次，且将视角移动到地图中心点。
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
        // 设置边框的颜色
        myLocationStyle.strokeColor(Color.TRANSPARENT);
        // 设置边框的填充色
        myLocationStyle.radiusFillColor(Color.TRANSPARENT);
        // 设置定位点图片
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.location));
        //自定义定位蓝点图标的锚点
        myLocationStyle.anchor((float) 0.5, 1);
        //设置定位蓝点的Style
        aMap.setMyLocationStyle(myLocationStyle);
        //定位监听
        aMap.setOnMyLocationChangeListener(this);
        //地图点击监听
        aMap.setOnMapClickListener(this);
    }

    private void initRecycler() {
        mList = new ArrayList<>();
        mAdapter = new AMapAddressAdapter(mList);
        binding.rvList.setLayoutManager(new LinearLayoutManager(context));
        binding.rvList.setAdapter(mAdapter);
    }

    private void initEvent() {
        binding.tvCancel.setOnClickListener(this);
        binding.tvSure.setOnClickListener(this);
        binding.tvFilter.setOnClickListener(this);
        binding.searchAddress.setOnEditorActionListener(this);
        mAdapter.setOnItemClickListener((adapter, view, position) -> {
            mIsMapClick = false;
            itemClick(position);
        });
    }

    /**
     * 地址列表点击
     */
    private void itemClick(int position) {
        mAdapter.setSelect(position);
        //
        selectEntity = mList.get(position);
        if (!mIsInitializedLatLng) {
            //初始化信息
            mIsInitializedLatLng = true;
            //设置当前城市
            mCurCity = selectEntity.getCity();
            //设置筛选标题
            binding.tvFilter.setText(String.format("%s", selectEntity.getCity()));
        }
        //判断是否需要添加覆盖物
        Observable.timer(300, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(aLong -> {
                        moveCamera(selectEntity.getLatitude(), selectEntity.getLongitude(), !mIsMapClick);
                    });

    }

    /**
     * 初始定位回调
     */
    @Override
    public void onMyLocationChange(Location location) {
        //是否开启定位
        if (!LocationUtil.isOpenLocation(context)) {
            binding.llLocMsg.setVisibility(View.VISIBLE);
            binding.llLocMsg.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    try {
                        startActivity(intent);
//                        finish();
                    } catch (ActivityNotFoundException ex) {
                        intent.setAction(Settings.ACTION_SETTINGS);
                        try {
                            startActivity(intent);
                        } catch (Exception e) {
                        }
                    }
                }
            });
        } else {
            binding.llLocMsg.setVisibility(View.GONE);
        }
        if (mIsInitializedLatLng) {
            return;
        }
        if (location == null) {
            return;
        }
        //设置当前定位经纬度
        latLngLocation = new LatLng(location.getLatitude(), location.getLongitude());
        //查询定位
        Bundle bundle = getIntent().getExtras();
        if (bundle == null) return;
        String keyword = bundle.getString("keyword");
        String city = bundle.getString("city");
        double latitude = bundle.getDouble("latitude");
        double longitude = bundle.getDouble("longitude");
        type = bundle.getInt("type", -1);
        //搜索定位
        if (latitude != 0 && longitude != 0) {
            searchByLatLng(latitude, longitude);
        } else if (!TextUtils.isEmpty(keyword) || !TextUtils.isEmpty(city)) {
            searchByCityAndKeyword(keyword, city);
        } else {
            //通过poi搜索获取当前定位信息
            //PoiSearch.Query(关键字,搜索类型,城市名称或编码)
            PoiSearch.Query query = new PoiSearch.Query(null, POI_TYPE, null);
            query.setPageSize(limit);
            query.setExtensions(extensions);
            PoiSearch poiSearch = new PoiSearch(context, query);
            //设置经纬度
            poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(location.getLatitude(), location.getLongitude()), 100));
            //设置搜索回调
            poiSearch.setOnPoiSearchListener(this);
            //开始搜索
            poiSearch.searchPOIAsyn();
        }
    }

    /**
     * 地图点击回调
     */
    @Override
    public void onMapClick(LatLng latLng) {
        mIsMapClick = true;
        //添加覆盖物
        addMarker(latLng);
        //搜索附近Poi
        LatLonPoint latLonPoint = new LatLonPoint(latLng.latitude, latLng.longitude);
        //PoiSearch.Query(关键字,搜索类型,城市名称或编码)
        PoiSearch.Query query = new PoiSearch.Query("", POI_TYPE, "");
        query.setPageSize(limit);
        query.setExtensions(extensions);
        PoiSearch poiSearch = new PoiSearch(context, query);
        //设置周边搜索的中心点以及半径
        poiSearch.setBound(new PoiSearch.SearchBound(latLonPoint, 1000));
        //设置搜索回调
        poiSearch.setOnPoiSearchListener(this);
        //开始搜索
        poiSearch.searchPOIAsyn();
    }

    /**
     * 添加覆盖物
     */
    private void addMarker(LatLng latLng) {
        //清除地图上marker等，定位点除外
        aMap.clear();
        //
        MarkerOptions markerOption = new MarkerOptions();
        markerOption.position(latLng);
        markerOption.icon(BitmapDescriptorFactory.fromResource(R.mipmap.parcker_map_position));
        //设置marker平贴地图效果
//        markerOption.setFlat(true);
        aMap.addMarker(markerOption);
    }

    /**
     * 搜索框回调
     */
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        closeKeybord();
        if (actionId == EditorInfo.IME_ACTION_SEARCH || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
            mIsMapClick = false;
            //PoiSearch.Query(关键字,搜索类型,城市名称或编码)
            PoiSearch.Query query = new PoiSearch.Query(binding.searchAddress.getText().toString(), POI_TYPE, mCurCity);
            query.setPageSize(limit);
            query.setExtensions(extensions);
            PoiSearch poiSearch = new PoiSearch(context, query);
            //设置搜索回调
            poiSearch.setOnPoiSearchListener(this);
            //开始搜索
            poiSearch.searchPOIAsyn();
        }
        return false;
    }

    /**
     * 获取Poi搜索结果
     */
    @Override
    public void onPoiSearched(PoiResult poiResult, int code) {
        //1000 成功
        if (code != 1000) return;
        mList.clear();
        //添加地址信息
        List<PoiItem> poiList = poiResult.getPois();
        if (poiList != null && poiList.size() > 0) {
            for (PoiItem poi : poiList) {
                //计算当前位置与定位点的距离
                float distance = 0;
                if (latLngLocation != null) {
                    LatLng current = new LatLng(poi.getLatLonPoint().getLatitude(), poi.getLatLonPoint().getLongitude());
                    distance = AMapUtils.calculateLineDistance(current, latLngLocation);
                }
                //添加当前位置信息
                mList.add(new AMapAddressEntity(poi.getProvinceName(), poi.getCityName(), poi.getAdName(),
                        poi.getTitle(), String.format("%s", NumberUtil.trim0(distance, 2)),
                        poi.getLatLonPoint().getLatitude(), poi.getLatLonPoint().getLongitude(),
                        poi.getProvinceCode(), poi.getCityCode(), poi.getAdCode()));
//                Timber.tag("Address Code").e("poi=%s", poi.toString());
            }
        } else {
            MToast.showToast(this, "没有搜到，请尝试其他关键词");
        }
        mAdapter.notifyDataSetChanged();
        //触发点击选中第一条地址
        if (!mList.isEmpty()) {
            binding.rvList.scrollToPosition(0);
            itemClick(0);
        }
    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int code) {

    }

    /**
     * 移动地图并标记
     */
    private void moveCamera(double latitude, double longitude, boolean addMarker) {
        LatLng latLng = new LatLng(latitude, longitude);
        //添加标记
        if (addMarker) {
            addMarker(latLng);
        }
        //将marker移动到地图中心
        aMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(latLng, zoomLevel, 0, 0)));
    }

    /**
     * 通过经纬度搜索地区
     */
    public void searchByLatLng(double latitude, double longitude) {
        //设置当前城市
        mIsMapClick = false;
/*        PoiSearch.Query query = new PoiSearch.Query("", POI_TYPE, "");
        query.setPageSize(limit);
        query.setExtensions(extensions);
        query.setLocation(new LatLonPoint(latitude, longitude));
        PoiSearch poiSearch = new PoiSearch(context, query);
        poiSearch.setOnPoiSearchListener(this);
        poiSearch.searchPOIAsyn();*/
        GeocodeSearch geocodeSearch = new GeocodeSearch(this);
        RegeocodeQuery regeocodeQuery=new RegeocodeQuery(new LatLonPoint(latitude,
                longitude), 100, GeocodeSearch.AMAP);
        geocodeSearch.getFromLocationAsyn(regeocodeQuery);
        geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
                if (i == 1000) {
                    if (regeocodeResult != null) {
                        float distance = 0;
                        RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();
                        List<AoiItem> aoiItems=regeocodeAddress.getAois();
                        String address=regeocodeAddress.getFormatAddress();
                        if (latLngLocation != null) {
                            LatLng current = new LatLng(latitude, longitude);
                            distance = AMapUtils.calculateLineDistance(current, latLngLocation);
                        }
                        //添加当前位置信息
                        mList.add(new AMapAddressEntity(regeocodeAddress.getProvince(), regeocodeAddress.getCity(), regeocodeAddress.getDistrict(),
                                address, String.format("%s", NumberUtil.trim0(distance, 2)),
                                latitude, longitude,
                                "", "", regeocodeAddress.getAdCode()));

                        mAdapter.notifyDataSetChanged();
                        //触发点击选中第一条地址
                        if (!mList.isEmpty()) {
                            binding.rvList.scrollToPosition(0);
                            itemClick(0);
                        }
                        //延迟移动地图，防止没移动
                        Completable.timer(500, TimeUnit.MILLISECONDS)
                                .subscribe(new CompletableObserver() {
                                    @Override
                                    public void onSubscribe(Disposable d) {
                                    }

                                    @Override
                                    public void onComplete() {
                                        moveCamera(latitude, longitude, true);
                                    }

                                    @Override
                                    public void onError(Throwable e) {

                                    }
                                });

                    }else{
                        MToast.showToast(AMapDialog.this, "未搜索到相关位置");
                    }
                }
            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

            }
        });
    }

    /**
     * 通过城市和关键字搜索地区
     */
    public void searchByCityAndKeyword(String keyword, String cityName) {
        //设置当前城市
        mCurCity = cityName;
        mIsMapClick = false;
        PoiSearch.Query query = new PoiSearch.Query(keyword, POI_TYPE, cityName);
        query.setPageSize(limit);
        query.setExtensions(extensions);
        PoiSearch poiSearch = new PoiSearch(context, query);
        poiSearch.setOnPoiSearchListener(this);
        poiSearch.searchPOIAsyn();
    }

    /**
     * 获取省市区数据
     */
    private void getAddress() {
        AddressHelper.getInstance().getAllArea(new AddressHelper.AddressCallBack() {

            @Override
            public void threeData(List<AddressEntity> provinceList, List<List<AddressEntity>> cityList, List<List<List<AddressEntity>>> districtList) {
                //初始化省市区选择器
                mPicker = PickerHelper.with(context).getCommonPicker("选择地区", provinceList, cityList, districtList, (options1, options2, options3, v) -> {
                    AddressEntity city = cityList.get(options1).get(options2);
                    AddressEntity area;
                    if (districtList.get(options1).get(options2) != null && districtList.get(options1).get(options2).size() > 0) {
                        area = districtList.get(options1).get(options2).get(options3);
                    } else {
                        area = cityList.get(options1).get(options2);
                    }
                    //设置筛选框
                    binding.tvFilter.setText(area.getName());
                    searchByCityAndKeyword(area.getName(), city.getName());
                });
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_cancel:
                finishWithAnim();
                break;
            case R.id.tv_sure:
                confirmSelect();
                break;
            case R.id.tvFilter:
                //省市区选择器
                if (mPicker == null) {
                    MToast.showToast(context, "数据加载中");
                } else {
                    closeKeybord();
                    mPicker.show();
                }
                break;
        }
    }

    private void confirmSelect() {
        if (mPicker == null) {
            MToast.showToast(this, "数据加载中");
            return;
        }
        if (selectEntity == null) {
            MToast.showToast(this, "请选择地址后确定");
            return;
        }
        //查询城市编码
        AddressHelper.getInstance().findCode(selectEntity);
        selectEntity.setType(type);
        Intent intent = new Intent();
        intent.putExtra(RouterKey.DATA, selectEntity);
        setResult(RESULT_OK, intent);
        finishWithAnim();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        overridePendingTransition(R.anim.dialog_enter_anim, R.anim.dialog_exit_anim);
    }

    private void finishWithAnim() {
        finish();
        overridePendingTransition(R.anim.dialog_enter_anim, R.anim.dialog_exit_anim);
    }

    private void closeKeybord() {
        if (getCurrentFocus() != null) {
            ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
                    .hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    /**
     * 获取地址
     */
    public static AMapAddressEntity get(Intent data) {
        if (data == null) {
            return null;
        }
        return data.getParcelableExtra(RouterKey.DATA);
    }

    @Override
    public void onResume() {
        super.onResume();
        binding.searchMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        binding.searchMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        binding.searchMapView.onDestroy();
    }
}
